package com.bupt.service.common.impl;

import com.bupt.Factory.ProjectFactory;
import com.bupt.annotation.MParam;
import com.bupt.basic.BasicNetWork;
import com.bupt.basic.DemandReportService;
import com.bupt.basic.IBasicNetWork;
import com.bupt.basic.Project;
import com.bupt.dto.sys.LoginUserDto;
import com.bupt.entity.Route;
import com.bupt.exception.BaseException;
import com.bupt.service.common.KangHuiService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.*;
import org.omg.CORBA.PUBLIC_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import springfox.documentation.schema.Entry;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service("tbKangHuiService")
public class KangHuiServiceImpl implements KangHuiService {

    //存储数据，以便给excel导出用
    List<TbKangHuiServiceUtil.DanDuanDto> zuheExcelData = new ArrayList<>();
    List<TbKangHuiServiceUtil.DanDuanOneByOneDto> oneByOneExcelData = new ArrayList<>();

    //组合抗毁
    @Override
    public Object getBreak(@MParam("当前的登陆的用户") LoginUserDto loginUserDto, @MParam("项目的ID") String pId,
                           @MParam("组合断开的fiberId集合") List<String> fiberLinkIds,
                           @MParam("组合断开的节点集合") List<String> nodeIds
    ) throws BaseException {
        Project project = ProjectFactory.getObjectFromFile(pId, ProjectFactory.storePath);
        List<DemandReportService> demandReportServices =project.getDemandList();
        BasicNetWork basicNetWork =project.getBasicNetWork();

        if (basicNetWork == null) throw new BaseException("此项目无基础网络");
        if (!project.isPlanned()) throw new BaseException("该项目未经过规划");
        String strategy = "BALANCE";
        List<TbKangHuiServiceUtil.DanDuanDto> res = new ArrayList<>();
        Set<String> fiberLinkSet = new HashSet<String>(fiberLinkIds);

        //把节点的单断实为与它有关的链路单断
        for (BasicNetWork.BasicLink f : basicNetWork.getFiberLinks()) {
            for (String nodeId : nodeIds) {
                if (f.getNodeHead().equals(nodeId) || f.getNodeTail().equals(nodeId)) {
                    fiberLinkSet.add(f.getId());
                }
            }
        }
        //下面所有的t都指代业务！！
        for (DemandReportService t : demandReportServices) {
            //若此业务规划后无工作路由，不用抗毁，怎么都不可能
            if (t.getWorkRoute() == null) {
                continue;
            }
            //以下属性为接下来可能算新的恢复路由所做的数据准备
            BasicNetWork.BasicNode origin = basicNetWork.getNodeMap().get(t.getNodeHead());
            BasicNetWork.BasicNode destination = basicNetWork.getNodeMap().get(t.getNodeTail());
            Set<BasicNetWork.BasicNode> nodes = new HashSet<>(basicNetWork.getNodeList());

            //判断工作和保护两路由是否受影响
            boolean flagWork = false;
            boolean flagProtect = false;
            for (String fiberLinkId : fiberLinkSet) {
                //被影响则返回true
                if (TbKangHuiServiceUtil.judgeAffected(fiberLinkId, t.getLayer(), t.getWorkRoute().getLinkList(),
                        basicNetWork)) {
                    flagWork = true;
                }
                if (TbKangHuiServiceUtil.judgeAffected(fiberLinkId, t.getLayer(), t.getProtectRoute().getLinkList(),
                        basicNetWork)) {
                    flagProtect = true;
                }
            }
            boolean recoveryFlag = false;//业务是否能恢复
            //以下部分代表业务受影响——flagWork为真即工作路由不能用
            if (flagWork) {
                switch (t.getProtect()) {
                    //无保护状态
                    case "无保护":
                        res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                t.getYear(), t.getLayer(), t.getProtect(), false, "工作路由受影响", null, null,
                                TbKangHuiServiceUtil.routeType(t.getWorkRoute()), null));
                        break;
                    //保护1+1
                    case "1+1":
                        if (flagProtect) {
                            res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                    t.getYear(), t.getLayer(), t.getProtect(), false, "工作路由和保护路由都受影响", null, null,
                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                        } else {
                            res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                    t.getYear(), t.getLayer(), t.getProtect(), true, "", TbKangHuiServiceUtil.routeType(t.getProtectRoute()), null,
                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                        }
                        break;
                    //1+恢复
                    case "重路由":
                        //先找出可使用的链路，再find算法找到具体链路组，最后生成路由类型对象
                        Set<BasicNetWork.BasicLink> maybeLinks = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSet, t.getBandwidthNum(), basicNetWork);
                        List<BasicNetWork.BasicLink> recoverydLinks = TbAlgorithms.findNoMust(maybeLinks, nodes, origin, destination, strategy, basicNetWork);
                        if (recoverydLinks == null || recoverydLinks.isEmpty()) {
                            res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                    t.getYear(), t.getLayer(), t.getProtect(), false, "该业务无法为工作路由找到恢复路由", null, null,
                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), null));
                        } else {
                            Route route = TbKangHuiServiceUtil.generateRoute(recoverydLinks, origin, destination);
                            res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                    t.getYear(), t.getLayer(), t.getProtect(), true, "",
                                    TbKangHuiServiceUtil.routeType(route), null,
                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), null));
                        }
                        break;
                    //1+1+恢复
                    case "1+1+重路由":
                        //如果保护路由受影响
                        if (flagProtect) {
                            Set<BasicNetWork.BasicLink> maybeLinks11 = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSet, t.getBandwidthNum(), basicNetWork);
                            List<BasicNetWork.BasicLink> recoverydLinks11 = TbAlgorithms.findNoMust(maybeLinks11, nodes, origin, destination, strategy, basicNetWork);
                            if (recoverydLinks11 == null || recoverydLinks11.isEmpty()) {
                                res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                        t.getYear(), t.getLayer(), t.getProtect(), false, "该业务无法为工作路由找到恢复路由", null, null,
                                        TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                            } else {
                                Route route = TbKangHuiServiceUtil.generateRoute(recoverydLinks11, origin, destination);
                                res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                        t.getYear(), t.getLayer(), t.getProtect(), true, "",
                                        TbKangHuiServiceUtil.routeType(route), null,
                                        TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                            }
                        }
                        //保护路由未受影响
                        else {
                            res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                    t.getYear(), t.getLayer(), t.getProtect(), true, "", TbKangHuiServiceUtil.routeType(t.getProtectRoute()), null,
                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                        }
                        break;
                    //永久1+1
                    case "永久1+1":
                        //如果工作和保护路由都受影响，要找两条底层fiberLink无交集的恢复路由才算成功
                        if (flagProtect) {
                            Set<BasicNetWork.BasicLink> PERMANENTLinks = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSet, t.getBandwidthNum(), basicNetWork);
                            List<BasicNetWork.BasicLink> recoverPermanentLinks = TbAlgorithms.findNoMust(PERMANENTLinks, nodes, origin, destination, strategy, basicNetWork);
                            //找第二套路由
                            List<BasicNetWork.BasicLink> recoverPermanentLinks2 = null;
                            if (recoverPermanentLinks != null && !recoverPermanentLinks.isEmpty()) {
                                Set<String> fiberLinkSetNew = new HashSet<String>(fiberLinkSet);
                                for (BasicNetWork.BasicLink basicLink : recoverPermanentLinks) {
                                    for (String fiberLinkId : basicLink.getFiberLinkIdSet()) {
                                        fiberLinkSetNew.add(fiberLinkId);
                                    }
                                }
                                Set<BasicNetWork.BasicLink> PERMANENTLinks2 = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSetNew, t.getBandwidthNum(), basicNetWork);
                                recoverPermanentLinks2 = TbAlgorithms.findNoMust(PERMANENTLinks2, nodes, origin, destination, strategy, basicNetWork);
                            }

                            //如果两套路由有一套不存在，都恢复失败；都存在则恢复成功
                            if (recoverPermanentLinks == null || recoverPermanentLinks.isEmpty() || recoverPermanentLinks2 == null || recoverPermanentLinks2.isEmpty()) {
                                res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                        t.getYear(), t.getLayer(), t.getProtect(), false, "无法同时使工作和保护路由得到恢复", null, null,
                                        TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                            } else {
                                Route route1 = TbKangHuiServiceUtil.generateRoute(recoverPermanentLinks, origin, destination);
                                Route route2 = TbKangHuiServiceUtil.generateRoute(recoverPermanentLinks2, origin, destination);
                                res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                        t.getYear(), t.getLayer(), t.getProtect(), true, "工作和保护路由同时恢复成功",
                                        TbKangHuiServiceUtil.routeType(route1), TbKangHuiServiceUtil.routeType(route2),
                                        TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                            }
                        }
                        //永久1+1工作路由受影响，保护路由未受影响
                        else {
                            //添加保护路由下的底层fiber进去 去排除
                            Set<String> fiberLinkSetAddPro = new HashSet<String>(fiberLinkSet);
                            for (String protectId : t.getProtectRoute().getLinkList()) {
                                fiberLinkSetAddPro.add(protectId);
                            }
                            Set<BasicNetWork.BasicLink> maybeLinks111 = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSetAddPro, t.getBandwidthNum(), basicNetWork);
                            List<BasicNetWork.BasicLink> recoverydLinks111 = TbAlgorithms.findNoMust(maybeLinks111, nodes, origin, destination, strategy, basicNetWork);
                            if (recoverydLinks111 == null || recoverydLinks111.isEmpty()) {
                                res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                        t.getYear(), t.getLayer(), t.getProtect(), false, "把保护路由给工作路由,但保护路由未能恢复",
                                        TbKangHuiServiceUtil.routeType(t.getProtectRoute()), null,
                                        TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                            } else {
                                Route route = TbKangHuiServiceUtil.generateRoute(recoverydLinks111, origin, destination);
                                res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(), t.getYear(), t.getLayer(), t.getProtect(), true, "",
                                        TbKangHuiServiceUtil.routeType(t.getProtectRoute()), TbKangHuiServiceUtil.routeType(route),
                                        TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                            }
                        }
                        break;
                }
            }
            //针对永久1+1，工作路由没受影响，保护路由受影响情况
            if (!flagWork && flagProtect && t.getProtect().equals("永久1+1")) {
                //添加工作路由下的底层fiber进去 去排除
                Set<String> fiberLinkSetAddWork = new HashSet<String>(fiberLinkSet);
                for (String protectId : t.getWorkRoute().getLinkList()) {
                    fiberLinkSetAddWork.add(protectId);
                }
                Set<BasicNetWork.BasicLink> maybeLinks = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSetAddWork, t.getBandwidthNum(), basicNetWork);

                List<BasicNetWork.BasicLink> recoverydLinks = TbAlgorithms.findNoMust(maybeLinks, nodes, origin, destination, strategy, basicNetWork);
                if (recoverydLinks == null || recoverydLinks.isEmpty()) {
                    res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                            t.getYear(), t.getLayer(), t.getProtect(), false, "保护降级，保护路由受损无法恢复",
                            TbKangHuiServiceUtil.routeType(t.getWorkRoute()), null,
                            TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                } else {
                    Route route = TbKangHuiServiceUtil.generateRoute(recoverydLinks, origin, destination);
                    res.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                            t.getYear(), t.getLayer(), t.getProtect(), true, "保护路由受损后恢复成功",
                            TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(route),
                            TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                }
            }
        }
        zuheExcelData = res;
        return res;
    }

    //依次单断抗毁
    public Object getBreakOneByOne(@MParam("当前的登陆的用户") LoginUserDto loginUserDto,
                                   @MParam("项目的ID") String pId, @MParam("组合断开的fiberId集合") List<String> fiberLinkIds,
                                   @MParam("组合断开的节点集合") List<String> nodeIds
    ) throws BaseException {
        Project project = ProjectFactory.getObjectFromFile(pId, ProjectFactory.storePath);
        List<DemandReportService> demandReportServices =project.getDemandList();
        BasicNetWork basicNetWork = project.getNetWork();

        if (basicNetWork == null) throw new BaseException("此项目无基础网络");
        if (!project.isPlanned()) throw new BaseException("该项目未经过规划");
        String strategy = "BALANCE";
        List<TbKangHuiServiceUtil.DanDuanOneByOneDto> res = new ArrayList<>();

        if (fiberLinkIds != null) {
            for (String fiberLinkId : fiberLinkIds) {
                Set<String> fiberLinkSet = new HashSet<String>();
                fiberLinkSet.add(fiberLinkId);
                //fiberLinkSet的size始终为1

                List<TbKangHuiServiceUtil.DanDuanDto> danDuanDtos = new ArrayList<>();
                //下面所有的t都指代业务！！
                for (DemandReportService t : demandReportServices) {
                    if (t.getWorkRoute() == null || t.getWorkRoute().getLinkList() == null || t.getWorkRoute().getLinkList().isEmpty()) {
                        continue;
                    }
                    //以下属性为接下来可能算新的恢复路由所做的数据准备
                    BasicNetWork.BasicNode origin = basicNetWork.getNodeMap().get(t.getNodeHead());
                    BasicNetWork.BasicNode destination = basicNetWork.getNodeMap().get(t.getNodeTail());
                    Set<BasicNetWork.BasicNode> nodes = new HashSet<>(basicNetWork.getNodeList());

                    //判断工作和保护两路由是否受影响
                    boolean flagWork = false;
                    boolean flagProtect = false;
                    //被影响则返回true
                    if (TbKangHuiServiceUtil.judgeAffected(fiberLinkId, t.getLayer(), t.getWorkRoute().getLinkList(),
                            basicNetWork)) {
                        flagWork = true;
                    }
                    if (TbKangHuiServiceUtil.judgeAffected(fiberLinkId, t.getLayer(), t.getProtectRoute().getLinkList(),
                            basicNetWork)) {
                        flagProtect = true;
                    }
                    //以下部分代表业务受影响——flagWork为真即工作路由不能用
                    if (flagWork) {
                        switch (t.getProtect()) {
                            //无保护状态
                            case "无保护":
                                danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                        t.getYear(), t.getLayer(), t.getProtect(), false, "工作路由受影响", null, null,
                                        TbKangHuiServiceUtil.routeType(t.getWorkRoute()), null));
                                break;
                            //保护1+1
                            case "1+1":
                                if (flagProtect) {
                                    danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                            t.getYear(), t.getLayer(), t.getProtect(), false, "工作路由和保护路由都受影响", null, null,
                                            TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                } else {
                                    danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                            t.getYear(), t.getLayer(), t.getProtect(), true, "", TbKangHuiServiceUtil.routeType(t.getProtectRoute()), null,
                                            TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                }
                                break;
                            //1+恢复
                            case "重路由":
                                //先找出可能可使用的链路，再find算法找到具体链路组，最后生成路由类型对象
                                Set<BasicNetWork.BasicLink> maybeLinks = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSet, t.getBandwidthNum(), basicNetWork);
                                List<BasicNetWork.BasicLink> recoverydLinks = TbAlgorithms.findNoMust(maybeLinks, nodes, origin, destination, strategy, basicNetWork);
                                if (recoverydLinks == null || recoverydLinks.isEmpty()) {
                                    danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                            t.getYear(), t.getLayer(), t.getProtect(), false, "该业务无法为工作路由找到恢复路由", null, null,
                                            TbKangHuiServiceUtil.routeType(t.getWorkRoute()), null));
                                } else {
                                    Route route = TbKangHuiServiceUtil.generateRoute(recoverydLinks, origin, destination);
                                    danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                            t.getYear(), t.getLayer(), t.getProtect(), true, "", TbKangHuiServiceUtil.routeType(route), null,
                                            TbKangHuiServiceUtil.routeType(t.getWorkRoute()), null));
                                }
                                break;
                            //1+1+恢复
                            case "1+1+重路由":
                                //如果保护路由受影响
                                if (flagProtect) {
                                    Set<BasicNetWork.BasicLink> maybeLinks11 = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSet, t.getBandwidthNum(), basicNetWork);
                                    List<BasicNetWork.BasicLink> recoverydLinks11 = TbAlgorithms.findNoMust(maybeLinks11, nodes, origin, destination, strategy, basicNetWork);
                                    if (recoverydLinks11 == null || recoverydLinks11.isEmpty()) {
                                        danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                t.getYear(), t.getLayer(), t.getProtect(), false, "该业务无法为工作路由找到恢复路由", null, null,
                                                TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                    } else {
                                        Route route = TbKangHuiServiceUtil.generateRoute(recoverydLinks11, origin, destination);
                                        danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                t.getYear(), t.getLayer(), t.getProtect(), true, "", TbKangHuiServiceUtil.routeType(route), null,
                                                TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                    }
                                }
                                //保护路由未受影响
                                else {
                                    danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                            t.getYear(), t.getLayer(), t.getProtect(), true, "", TbKangHuiServiceUtil.routeType(t.getProtectRoute()), null,
                                            TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                }
                                break;
                            //永久1+1
                            case "永久1+1":
                                //如果保护路由受影响
                                if (flagProtect) {
                                    Set<BasicNetWork.BasicLink> PERMANENTLinks = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSet, t.getBandwidthNum(), basicNetWork);
                                    List<BasicNetWork.BasicLink> recoverPermanentLinks = TbAlgorithms.findNoMust(PERMANENTLinks, nodes, origin, destination, strategy, basicNetWork);
                                    //找第二套路由
                                    List<BasicNetWork.BasicLink> recoverPermanentLinks2 = null;
                                    if (recoverPermanentLinks != null && !recoverPermanentLinks.isEmpty()) {
                                        Set<String> fiberLinkSetNew = new HashSet<String>(fiberLinkSet);
                                        for (BasicNetWork.BasicLink basicLink : recoverPermanentLinks) {
                                            for (String fiberId : basicLink.getFiberLinkIdSet()) {
                                                fiberLinkSetNew.add(fiberId);
                                            }
                                        }
                                        Set<BasicNetWork.BasicLink> PERMANENTLinks2 = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSetNew, t.getBandwidthNum(), basicNetWork);
                                        recoverPermanentLinks2 = TbAlgorithms.findNoMust(PERMANENTLinks2, nodes, origin, destination, strategy, basicNetWork);
                                    }

                                    //如果两套路由有一套不存在，都恢复失败；都存在则恢复成功
                                    if (recoverPermanentLinks == null || recoverPermanentLinks.isEmpty() || recoverPermanentLinks2 == null || recoverPermanentLinks2.isEmpty()) {
                                        danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                t.getYear(), t.getLayer(), t.getProtect(), false, "无法同时使工作和保护路由得到恢复", null, null,
                                                TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                    } else {
                                        Route route1 = TbKangHuiServiceUtil.generateRoute(recoverPermanentLinks, origin, destination);
                                        Route route2 = TbKangHuiServiceUtil.generateRoute(recoverPermanentLinks2, origin, destination);
                                        danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                t.getYear(), t.getLayer(), t.getProtect(), true, "工作和保护路由同时恢复成功",
                                                TbKangHuiServiceUtil.routeType(route1), TbKangHuiServiceUtil.routeType(route2),
                                                TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                    }
                                }
                                //保护路由未受影响
                                else {
                                    //添加保护路由下的底层fiber进去 去排除
                                    Set<String> fiberLinkSetAddPro = new HashSet<String>(fiberLinkSet);
                                    for (String protectId : t.getProtectRoute().getLinkList()) {
                                        fiberLinkSetAddPro.add(protectId);
                                    }
                                    Set<BasicNetWork.BasicLink> maybeLinks111 = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSetAddPro, t.getBandwidthNum(), basicNetWork);
                                    List<BasicNetWork.BasicLink> recoverydLinks111 = TbAlgorithms.findNoMust(maybeLinks111, nodes, origin, destination, strategy, basicNetWork);
                                    if (recoverydLinks111 == null || recoverydLinks111.isEmpty()) {
                                        danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                t.getYear(), t.getLayer(), t.getProtect(), false, "把保护路由给工作路由,但保护路由未能恢复",
                                                TbKangHuiServiceUtil.routeType(t.getProtectRoute()), null,
                                                TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                    } else {
                                        Route route = TbKangHuiServiceUtil.generateRoute(recoverydLinks111, origin, destination);
                                        danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                t.getYear(), t.getLayer(), t.getProtect(), true, "",
                                                TbKangHuiServiceUtil.routeType(t.getProtectRoute()), TbKangHuiServiceUtil.routeType(route),
                                                TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                    }
                                }
                                break;
                        }
                    }
                    //针对永久1+1，工作路由没受影响，保护路由受影响情况
                    if (!flagWork && flagProtect && t.getProtect().equals("永久1+1")) {
                        //添加工作路由下的底层fiber进去 去排除
                        Set<String> fiberLinkSetAddWork = new HashSet<String>(fiberLinkSet);
                        for (String protectId : t.getWorkRoute().getLinkList()) {
                            fiberLinkSetAddWork.add(protectId);
                        }
                        Set<BasicNetWork.BasicLink> maybeLinks = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSetAddWork, t.getBandwidthNum(), basicNetWork);

                        List<BasicNetWork.BasicLink> recoverydLinks = TbAlgorithms.findNoMust(maybeLinks, nodes, origin, destination, strategy, basicNetWork);
                        if (recoverydLinks == null || recoverydLinks.isEmpty()) {
                            danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                    t.getYear(), t.getLayer(), t.getProtect(), false, "保护降级，保护路由受损无法恢复", TbKangHuiServiceUtil.routeType(t.getWorkRoute()), null,
                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                        } else {
                            Route route = TbKangHuiServiceUtil.generateRoute(recoverydLinks, origin, destination);
                            danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                    t.getYear(), t.getLayer(), t.getProtect(), true, "保护路由受损后恢复成功", TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(route),
                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                        }
                    }
                }
                String fiberName = "";
                if (basicNetWork.getFiberLinks() != null) {
                    for (BasicNetWork.BasicLink fiberLink : basicNetWork.getFiberLinks()) {
                        if (fiberLink.getId().equals(fiberLinkId)) {
                            fiberName = fiberLink.getName();
                            break;
                        }
                    }
                }
                res.add(new TbKangHuiServiceUtil.DanDuanOneByOneDto(fiberLinkId, fiberName, "link", danDuanDtos));
            }
        }
        if (nodeIds != null) {
            for (String nodeId : nodeIds) {
                //由nodeId找到与之相关的fiberLinkId组
                Set<String> fiberLinkSet = new HashSet<>();
                if (basicNetWork.getFiberLinks() != null) {
                    for (BasicNetWork.BasicLink f : basicNetWork.getFiberLinks()) {
                        if (f.getNodeHead().equals(nodeId) || f.getNodeTail().equals(nodeId)) {
                            fiberLinkSet.add(f.getId());
                        }
                    }
                    List<TbKangHuiServiceUtil.DanDuanDto> danDuanDtos = new ArrayList<>();
                    //下面所有的t都指代业务！！
                    for (DemandReportService t : demandReportServices) {
                        if (t.getWorkRoute() == null || t.getWorkRoute().getLinkList() == null || t.getWorkRoute().getLinkList().isEmpty()) {
                            continue;
                        }
                        //以下属性为接下来可能算新的恢复路由所做的数据准备
                        BasicNetWork.BasicNode origin = basicNetWork.getNodeMap().get(t.getNodeHead());
                        BasicNetWork.BasicNode destination = basicNetWork.getNodeMap().get(t.getNodeTail());
                        Set<BasicNetWork.BasicNode> nodes = new HashSet<>(basicNetWork.getNodeList());
                        //判断工作和保护两路由是否受影响
                        boolean flagWork = false;
                        boolean flagProtect = false;
                        for (String fiberLinkId : fiberLinkSet) {
                            if (TbKangHuiServiceUtil.judgeAffected(fiberLinkId, t.getLayer(), t.getWorkRoute().getLinkList(), basicNetWork)) {
                                flagWork = true;
                            }
                            if (TbKangHuiServiceUtil.judgeAffected(fiberLinkId, t.getLayer(), t.getProtectRoute().getLinkList(), basicNetWork)) {
                                flagProtect = true;
                            }
                        }
                        //以下部分代表业务受影响——flagWork为真即工作路由不能用
                        if (flagWork) {
                            switch (t.getProtect()) {
                                //无保护状态
                                case "无保护":
                                    danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                            t.getYear(), t.getLayer(), t.getProtect(), false, "工作路由受影响", null, null,
                                            TbKangHuiServiceUtil.routeType(t.getWorkRoute()), null));
                                    break;
                                //保护1+1
                                case "1+1":
                                    if (flagProtect) {
                                        danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                t.getYear(), t.getLayer(), t.getProtect(), false, "工作路由和保护路由都受影响", null, null,
                                                TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                    } else {
                                        danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                t.getYear(), t.getLayer(), t.getProtect(), true, "", TbKangHuiServiceUtil.routeType(t.getProtectRoute()), null,
                                                TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                    }
                                    break;
                                //1+恢复
                                case "重路由":
                                    //先找出可能可使用的链路，再find算法找到具体链路组，最后生成路由类型对象
                                    Set<BasicNetWork.BasicLink> maybeLinks = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSet, t.getBandwidthNum(), basicNetWork);
                                    List<BasicNetWork.BasicLink> recoverydLinks = TbAlgorithms.findNoMust(maybeLinks, nodes, origin, destination, strategy, basicNetWork);
                                    if (recoverydLinks == null || recoverydLinks.isEmpty()) {
                                        danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                t.getYear(), t.getLayer(), t.getProtect(), false, "该业务无法为工作路由找到恢复路由", null, null,
                                                TbKangHuiServiceUtil.routeType(t.getWorkRoute()), null));
                                    } else {
                                        Route route = TbKangHuiServiceUtil.generateRoute(recoverydLinks, origin, destination);
                                        danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                t.getYear(), t.getLayer(), t.getProtect(), true, "", TbKangHuiServiceUtil.routeType(route), null,
                                                TbKangHuiServiceUtil.routeType(t.getWorkRoute()), null));
                                    }
                                    break;
                                //1+1+恢复
                                case "1+1+重路由":
                                    //如果保护路由受影响
                                    if (flagProtect) {
                                        Set<BasicNetWork.BasicLink> maybeLinks11 = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSet, t.getBandwidthNum(), basicNetWork);
                                        List<BasicNetWork.BasicLink> recoverydLinks11 = TbAlgorithms.findNoMust(maybeLinks11, nodes, origin, destination, strategy, basicNetWork);
                                        if (recoverydLinks11 == null || recoverydLinks11.isEmpty()) {
                                            danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                    t.getYear(), t.getLayer(), t.getProtect(), false, "该业务无法为工作路由找到恢复路由", null, null,
                                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                        } else {
                                            Route route = TbKangHuiServiceUtil.generateRoute(recoverydLinks11, origin, destination);
                                            danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                    t.getYear(), t.getLayer(), t.getProtect(), true, "", TbKangHuiServiceUtil.routeType(route), null,
                                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                        }
                                    }
                                    //保护路由未受影响
                                    else {
                                        danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                t.getYear(), t.getLayer(), t.getProtect(), true, "", TbKangHuiServiceUtil.routeType(t.getProtectRoute()), null,
                                                TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                    }
                                    break;
                                //永久1+1
                                case "永久1+1":
                                    //如果保护路由受影响
                                    if (flagProtect) {
                                        Set<BasicNetWork.BasicLink> PERMANENTLinks = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSet, t.getBandwidthNum(), basicNetWork);
                                        List<BasicNetWork.BasicLink> recoverPermanentLinks = TbAlgorithms.findNoMust(PERMANENTLinks, nodes, origin, destination, strategy, basicNetWork);
                                        //找第二套路由
                                        List<BasicNetWork.BasicLink> recoverPermanentLinks2 = null;
                                        if (recoverPermanentLinks != null && !recoverPermanentLinks.isEmpty()) {
                                            Set<String> fiberLinkSetNew = new HashSet<String>(fiberLinkSet);
                                            for (BasicNetWork.BasicLink basicLink : recoverPermanentLinks) {
                                                for (String fiberId : basicLink.getFiberLinkIdSet()) {
                                                    fiberLinkSetNew.add(fiberId);
                                                }
                                            }
                                            Set<BasicNetWork.BasicLink> PERMANENTLinks2 = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSetNew, t.getBandwidthNum(), basicNetWork);
                                            recoverPermanentLinks2 = TbAlgorithms.findNoMust(PERMANENTLinks2, nodes, origin, destination, strategy, basicNetWork);
                                        }

                                        //如果两套路由有一套不存在，都恢复失败；都存在则恢复成功
                                        if (recoverPermanentLinks == null || recoverPermanentLinks.isEmpty() || recoverPermanentLinks2 == null || recoverPermanentLinks2.isEmpty()) {
                                            danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                    t.getYear(), t.getLayer(), t.getProtect(), false, "无法同时使工作和保护路由得到恢复", null, null,
                                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                        } else {
                                            Route route1 = TbKangHuiServiceUtil.generateRoute(recoverPermanentLinks, origin, destination);
                                            Route route2 = TbKangHuiServiceUtil.generateRoute(recoverPermanentLinks2, origin, destination);
                                            danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                    t.getYear(), t.getLayer(), t.getProtect(), true, "工作和保护路由同时恢复成功", TbKangHuiServiceUtil.routeType(route1), TbKangHuiServiceUtil.routeType(route2),
                                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                        }
                                    }
                                    //保护路由未受影响
                                    else {
                                        //添加保护路由下的底层fiber进去 去排除
                                        Set<String> fiberLinkSetAddPro = new HashSet<String>(fiberLinkSet);
                                        for (String protectId : t.getProtectRoute().getLinkList()) {
                                            fiberLinkSetAddPro.add(protectId);
                                        }
                                        Set<BasicNetWork.BasicLink> maybeLinks111 = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSetAddPro, t.getBandwidthNum(), basicNetWork);
                                        List<BasicNetWork.BasicLink> recoverydLinks111 = TbAlgorithms.findNoMust(maybeLinks111, nodes, origin, destination, strategy, basicNetWork);
                                        if (recoverydLinks111 == null || recoverydLinks111.isEmpty()) {
                                            danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                    t.getYear(), t.getLayer(), t.getProtect(), false, "把保护路由给工作路由,但保护路由未能恢复", TbKangHuiServiceUtil.routeType(t.getProtectRoute()), null,
                                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                        } else {
                                            Route route = TbKangHuiServiceUtil.generateRoute(recoverydLinks111, origin, destination);
                                            danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                                    t.getYear(), t.getLayer(), t.getProtect(), true, "",
                                                    TbKangHuiServiceUtil.routeType(t.getProtectRoute()), TbKangHuiServiceUtil.routeType(route),
                                                    TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                                        }
                                    }
                                    break;
                            }
                        }
                        //针对永久1+1，工作路由没受影响，保护路由受影响情况
                        if (!flagWork && flagProtect && t.getProtect().equals("永久1+1")) {
                            //添加工作路由下的底层fiber进去 去排除
                            Set<String> fiberLinkSetAddWork = new HashSet<String>(fiberLinkSet);
                            for (String protectId : t.getWorkRoute().getLinkList()) {
                                fiberLinkSetAddWork.add(protectId);
                            }
                            Set<BasicNetWork.BasicLink> maybeLinks = TbKangHuiServiceUtil.removeRelatedLinks(t.getLayer(), fiberLinkSetAddWork, t.getBandwidthNum(), basicNetWork);

                            List<BasicNetWork.BasicLink> recoverydLinks = TbAlgorithms.findNoMust(maybeLinks, nodes, origin, destination, strategy, basicNetWork);
                            if (recoverydLinks == null || recoverydLinks.isEmpty()) {
                                danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                        t.getYear(), t.getLayer(), t.getProtect(), false, "保护降级，保护路由受损无法恢复", TbKangHuiServiceUtil.routeType(t.getWorkRoute()), null,
                                        TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                            } else {
                                Route route = TbKangHuiServiceUtil.generateRoute(recoverydLinks, origin, destination);
                                danDuanDtos.add(new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                        t.getYear(), t.getLayer(), t.getProtect(), true, "保护路由受损后恢复成功", TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(route),
                                        TbKangHuiServiceUtil.routeType(t.getWorkRoute()), TbKangHuiServiceUtil.routeType(t.getProtectRoute())));
                            }
                        }
                    }
                    String nodeName = "";
                    if (basicNetWork.getFiberLinks() != null) {
                        for (BasicNetWork.BasicNode node : basicNetWork.getNodeList()) {
                            if (node.getNodeId().equals(nodeId)) {
                                nodeName = node.getName();
                                break;
                            }
                        }
                    }
                    res.add(new TbKangHuiServiceUtil.DanDuanOneByOneDto(nodeId, nodeName, "node", danDuanDtos));
                }
            }
        }
        oneByOneExcelData = res;
        return res;
    }

    @Override
    public HttpServletResponse zuheExport(HttpServletResponse response, @MParam("当前的登陆的用户") LoginUserDto loginUserDto,
                                          @MParam("项目的ID") String pId) throws Exception {
        File tempFile = new File(ProjectFactory.storePath + "多断的抗毁结果数据.xls");
        try {
            Project project = ProjectFactory.getObjectFromFile(pId, ProjectFactory.storePath);
            List<DemandReportService> demandReportServices =project.getDemandList();
            BasicNetWork basicNetWork = project.getNetWork();
            if (basicNetWork == null) throw new BaseException("该项目网络未找到");

            String[] headers = {"业务名称", "首节点", "末节点", "年份", "所属层", "保护类型", "是否恢复成功", "工作路由", "保护路由"};
            OutputStream out = new FileOutputStream(tempFile);
            //实例化Excel表格
            HSSFWorkbook workbook = new HSSFWorkbook();
            workbook.createSheet("多断的抗毁结果");
            if (zuheExcelData != null && zuheExcelData.size() != 0) {
                //exportExcel("test", headers, weaver, weaver.getTrafficList(), workbook);
                HSSFSheet sheet = workbook.getSheet("多断的抗毁结果");
                // 设置表格默认列宽度为15个字节
                sheet.setDefaultColumnWidth((short) 15);
                HSSFRow row = sheet.createRow(0);
                for (short i = 0; i < headers.length; i++) {
                    HSSFCell cell = row.createCell(i);
                    //cell.setCellStyle(style);
                    HSSFRichTextString text = new HSSFRichTextString(headers[i]);
                    cell.setCellValue(text);
                }
                int index = 1;
                for (TbKangHuiServiceUtil.DanDuanDto danDuanDto : zuheExcelData) {
                    row = sheet.createRow(index);
                    index++;
                    HSSFCell cell0 = row.createCell(0);
                    cell0.setCellValue(new HSSFRichTextString(danDuanDto.getName()));
                    //cell0.setCellValue(Double.parseDouble(textValue));
                    HSSFCell cell1 = row.createCell(1);
                    cell1.setCellValue(new HSSFRichTextString(danDuanDto.getSourceName()));
                    HSSFCell cell2 = row.createCell(2);
                    cell2.setCellValue(new HSSFRichTextString(danDuanDto.getTargetName()));
                    HSSFCell cell3 = row.createCell(3);
                    cell3.setCellValue(danDuanDto.getYear());
                    HSSFCell cell4 = row.createCell(4);
                    cell4.setCellValue(new HSSFRichTextString(danDuanDto.getLayer()));
                    HSSFCell cell5 = row.createCell(5);
                    cell5.setCellValue(new HSSFRichTextString(danDuanDto.getProtect()));
                    HSSFCell cell6 = row.createCell(6);
                    if (danDuanDto.isRecoveryFlag()) {
                        cell6.setCellValue(new HSSFRichTextString("恢复成功"));
                    } else {
                        cell6.setCellValue(new HSSFRichTextString("恢复失败"));
                    }

                    HSSFCell cell7 = row.createCell(7);
                    StringBuilder workRoute = new StringBuilder();
                    if (danDuanDto.getWorkRoute() != null) {
                        for (TbKangHuiServiceUtil.RouteLinkType link : danDuanDto.getWorkRoute().getLinklist()) {
                            String name = link.getName();
                            workRoute.append(name);
                            workRoute.append(";");
                        }
                        if (workRoute.length() == 0) {
                            cell7.setCellValue("");
                        } else {
                            cell7.setCellValue(new HSSFRichTextString(workRoute.toString()));
                        }
                    }

                    HSSFCell cell8 = row.createCell(8);
                    StringBuilder protectRoute = new StringBuilder();
                    if (danDuanDto.getProtectRoute() != null) {
                        for (TbKangHuiServiceUtil.RouteLinkType link : danDuanDto.getProtectRoute().getLinklist()) {
                            String name = link.getName();
                            protectRoute.append(name);
                            protectRoute.append(";");
                        }
                        if (protectRoute.length() == 0) {
                            cell8.setCellValue("");
                        } else {
                            cell8.setCellValue(new HSSFRichTextString(protectRoute.toString()));
                        }
                    }
                }
            } else throw new BaseException("此项目未经过多断的抗毁测试");
            workbook.write(out);
            out.close();
            BufferedInputStream fis = new BufferedInputStream(
                    new FileInputStream(ProjectFactory.storePath + "多断的抗毁结果数据.xls"));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            response.reset();
            response.addHeader("Content-Disposition", "attachment;filename=" + new String("多断的抗毁结果数据.xls".getBytes("UTF-8"), "ISO8859_1"));
            response.addHeader("Content-Length", "" + tempFile.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (tempFile != null && tempFile.exists()) {
                tempFile.delete();// 删除临时文件
            }
        }
        return response;
    }

    @Override
    public HttpServletResponse oneByOneExport(HttpServletResponse response, @MParam("当前的登陆的用户") LoginUserDto loginUserDto,
                                              @MParam("项目的ID") String pId) throws Exception {
        File tempFile = new File(ProjectFactory.storePath + "依次单断的抗毁结果.xls");
        try {
            Project project = ProjectFactory.getObjectFromFile(pId, ProjectFactory.storePath);
            List<DemandReportService> demandReportServices =project.getDemandList();
            BasicNetWork basicNetWork = project.getNetWork();
            if (basicNetWork == null) throw new BaseException("该项目网络未找到");

            String[] headers1 = {"故障网元", "受影响业务名称", "首节点", "末节点", "所属层", "年份", "保护级别", "恢复状态", "原工作路由", "原保护路由", "现工作路由", "现保护路由"};
            String[] headers2 = {"业务名称", "首节点", "末节点", "所属层", "保护级别", "受影响次数", "未恢复次数"};
            OutputStream out = new FileOutputStream(tempFile);
            //实例化Excel表格
            HSSFWorkbook workbook = new HSSFWorkbook();
            workbook.createSheet("故障分析");
            workbook.createSheet("故障结果");
            if (oneByOneExcelData != null && oneByOneExcelData.size() != 0) {
                HSSFSheet sheet = workbook.getSheet("故障分析");
                // 设置表格默认列宽度为15个字节
                sheet.setDefaultColumnWidth((short) 15);
                HSSFRow row = sheet.createRow(0);
                for (short i = 0; i < headers1.length; i++) {
                    HSSFCell cell = row.createCell(i);
                    //cell.setCellStyle(style);
                    HSSFRichTextString text = new HSSFRichTextString(headers1[i]);
                    cell.setCellValue(text);
                }
                int index = 1;
                for (TbKangHuiServiceUtil.DanDuanOneByOneDto danDuanOneByOneDto : oneByOneExcelData) {
                    int n = 0;//用n来记录当前循环到此网元故障后，受影响的第几个业务
                    for (TbKangHuiServiceUtil.DanDuanDto danDuanDto : danDuanOneByOneDto.getAffectedList()) {
                        row = sheet.createRow(index);
                        index++;
                        HSSFCell cell0 = row.createCell(0);
                        cell0.setCellValue(new HSSFRichTextString(danDuanOneByOneDto.getType() + ": " + danDuanOneByOneDto.getName()));
                        //cell0.setCellValue(Double.parseDouble(textValue));
                        HSSFCell cell1 = row.createCell(1);
                        cell1.setCellValue(new HSSFRichTextString(danDuanDto.getName()));
                        HSSFCell cell2 = row.createCell(2);
                        cell2.setCellValue(new HSSFRichTextString(danDuanDto.getSourceName()));
                        HSSFCell cell3 = row.createCell(3);
                        cell3.setCellValue(new HSSFRichTextString(danDuanDto.getTargetName()));
                        HSSFCell cell4 = row.createCell(4);
                        cell4.setCellValue(new HSSFRichTextString(danDuanDto.getLayer()));
                        HSSFCell cell5 = row.createCell(5);
                        cell5.setCellValue(danDuanDto.getYear());
                        HSSFCell cell6 = row.createCell(6);
                        cell6.setCellValue(new HSSFRichTextString(danDuanDto.getProtect()));
                        HSSFCell cell7 = row.createCell(7);
                        if (danDuanDto.isRecoveryFlag()) {
                            cell7.setCellValue(new HSSFRichTextString("恢复成功"));
                        } else {
                            cell7.setCellValue(new HSSFRichTextString("恢复失败"));
                        }
                        //原工作路由和原来保护路由
                        HSSFCell cell8 = row.createCell(8);
                        StringBuilder workRoutePrev = new StringBuilder();
                        if (danDuanOneByOneDto.getAffectedList().get(n).getWorkRoutePrev() != null) {
                            for (TbKangHuiServiceUtil.RouteLinkType link : danDuanOneByOneDto.getAffectedList().get(n).getWorkRoutePrev().getLinklist()) {
                                String name = link.getName();
                                workRoutePrev.append(name);
                                workRoutePrev.append(";");
                            }
                            if (workRoutePrev.length() == 0) {
                                cell8.setCellValue("");
                            } else {
                                cell8.setCellValue(new HSSFRichTextString(workRoutePrev.toString()));
                            }
                        }
                        HSSFCell cell9 = row.createCell(9);
                        StringBuilder protectRoutePrev = new StringBuilder();
                        if (danDuanOneByOneDto.getAffectedList().get(n).getProtectRoutePrev() != null) {
                            for (TbKangHuiServiceUtil.RouteLinkType link : danDuanOneByOneDto.getAffectedList().get(n).getProtectRoutePrev().getLinklist()) {
                                String name = link.getName();
                                protectRoutePrev.append(name);
                                protectRoutePrev.append(";");
                            }
                            if (protectRoutePrev.length() == 0) {
                                cell9.setCellValue("");
                            } else {
                                cell9.setCellValue(new HSSFRichTextString(protectRoutePrev.toString()));
                            }
                        }
                        //n+1
                        n++;
                        //现工作路由和原来保护路由
                        if (danDuanDto.getWorkRoute() != null) {
                            HSSFCell cell10 = row.createCell(10);
                            StringBuilder workRoute = new StringBuilder();
                            for (TbKangHuiServiceUtil.RouteLinkType link : danDuanDto.getWorkRoute().getLinklist()) {
                                String name = link.getName();
                                workRoute.append(name);
                                workRoute.append(";");
                            }
                            if (workRoute.length() == 0) {
                                cell10.setCellValue("");
                            } else {
                                cell10.setCellValue(new HSSFRichTextString(workRoute.toString()));
                            }
                        }
                        if (danDuanDto.getProtectRoute() != null) {
                            HSSFCell cell11 = row.createCell(11);
                            StringBuilder protectRoute = new StringBuilder();
                            for (TbKangHuiServiceUtil.RouteLinkType link : danDuanDto.getProtectRoute().getLinklist()) {
                                String name = link.getName();
                                protectRoute.append(name);
                                protectRoute.append(";");
                            }
                            if (protectRoute.length() == 0) {
                                cell11.setCellValue("");
                            } else {
                                cell11.setCellValue(new HSSFRichTextString(protectRoute.toString()));
                            }
                        }
                    }
                }
            } else throw new BaseException("此项目未经过依次单断的抗毁测试");

            //统计一些恢复数据
            Map<String, Integer> success = new HashMap<>();
            Map<String, Integer> failure = new HashMap<>();
            for (TbKangHuiServiceUtil.DanDuanOneByOneDto danDuanOneByOneDto : oneByOneExcelData) {
                for (TbKangHuiServiceUtil.DanDuanDto danDuanDto : danDuanOneByOneDto.getAffectedList()) {
                    String serviceName = danDuanDto.getName();
                    if (!success.containsKey(serviceName)) {
                        success.put(serviceName, 0);
                    }
                    if (!failure.containsKey(serviceName)) {
                        failure.put(serviceName, 0);
                    }
                    if (danDuanDto.isRecoveryFlag()) {
                        success.put(serviceName, success.get(serviceName) + 1);
                    } else {
                        failure.put(serviceName, failure.get(serviceName) + 1);
                    }
                }
            }
            HSSFSheet sheet2 = workbook.getSheet("故障结果");
            // 设置表格默认列宽度为15个字节
            sheet2.setDefaultColumnWidth((short) 15);
            HSSFRow row2 = sheet2.createRow(0);
            for (short i = 0; i < headers2.length; i++) {
                HSSFCell cell = row2.createCell(i);
                //cell.setCellStyle(style);
                HSSFRichTextString text = new HSSFRichTextString(headers2[i]);
                cell.setCellValue(text);
            }
            int index = 1;
            for (DemandReportService t : demandReportServices) {
                row2 = sheet2.createRow(index);
                index++;
                HSSFCell cell0 = row2.createCell(0);
                cell0.setCellValue(new HSSFRichTextString(t.getName()));
                HSSFCell cell1 = row2.createCell(1);
                cell1.setCellValue(new HSSFRichTextString(t.getNodeHeadName()));
                HSSFCell cell2 = row2.createCell(2);
                cell2.setCellValue(new HSSFRichTextString(t.getNodeTailName()));
                HSSFCell cell3 = row2.createCell(3);
                cell3.setCellValue(new HSSFRichTextString(t.getLayer()));
                HSSFCell cell4 = row2.createCell(4);
                cell4.setCellValue(new HSSFRichTextString(t.getProtect()));
                Integer successNum = success.get(t.getName());
                Integer failureNum = failure.get(t.getName());
                HSSFCell cell5 = row2.createCell(5);
                if (successNum == null) {
                    cell5.setCellValue(new HSSFRichTextString(null));
                } else {
                    cell5.setCellValue(successNum + failureNum);
                }
                HSSFCell cell6 = row2.createCell(6);
                if (failureNum == null) {
                    cell6.setCellValue(new HSSFRichTextString(null));
                } else {
                    cell6.setCellValue(failureNum);
                }
            }

            workbook.write(out);
            out.close();
            BufferedInputStream fis = new BufferedInputStream(
                    new FileInputStream(ProjectFactory.storePath + "依次单断的抗毁结果.xls"));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            response.reset();
            response.addHeader("Content-Disposition", "attachment;filename=" + new String("依次单断的抗毁结果.xls".getBytes("UTF-8"), "ISO8859_1"));
            response.addHeader("Content-Length", "" + tempFile.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (tempFile != null && tempFile.exists()) {
                tempFile.delete();// 删除临时文件
            }
        }
        return response;
    }

    @Override
    public Map<String, Double> getBreakRate(@MParam("当前的登陆的用户") LoginUserDto loginUserDto,
                                            @MParam("项目的ID") String pId) throws BaseException {
        Project project = ProjectFactory.getObjectFromFile(pId, ProjectFactory.storePath);
        List<DemandReportService> demandReportServices =project.getDemandList();
        BasicNetWork basicNetWork = project.getNetWork();
        if (basicNetWork == null) throw new BaseException("此项目无基础网络");
        if (!project.isPlanned()) throw new BaseException("该项目未经过规划");

        double allRecoveryRate;
        int allRecoveryTimes = 0;
        Map<DemandReportService, Boolean> trafficMap = new HashMap<>();
        for (DemandReportService t : demandReportServices) {
            trafficMap.put(t, false);
        }

        List<Double> recoveryRateList = new ArrayList<>();
        for (BasicNetWork.BasicLink f : basicNetWork.getFiberLinks()) {
            int affectedTimes = 0;
            int recoveryTimes = 0;
            //t表示业务
            for (DemandReportService t : demandReportServices) {
                if (t.getWorkRoute() == null || t.getWorkRoute().getLinkList() == null || t.getWorkRoute().getLinkList().isEmpty()) {
                    continue;
                }
                boolean flagWork = TbKangHuiServiceUtil.judgeAffected(f.getId(), t.getLayer(), t.getWorkRoute().getLinkList(),
                        basicNetWork);
                boolean flagProtect = TbKangHuiServiceUtil.judgeAffected(f.getId(), t.getLayer(), t.getProtectRoute().getLinkList(),
                        basicNetWork);
                if (flagWork) {
                    affectedTimes++;
                    //t.setEffect(t.getEffect() + 1);
                    if (!flagProtect) { //t.setFail(t.getFail() + 1);
                        recoveryTimes++;
                        allRecoveryTimes++;//受影响且保护路由不受影响
                        if (!trafficMap.get(t)) trafficMap.put(t, true);
                    }
                }
            }
            if (affectedTimes == 0) {
                continue;
            }
            recoveryRateList.add(recoveryTimes * 1.0 / affectedTimes * 1.0);
        }

//        allRecoveryRate = allRecoveryTimes * 1.0 / (demandReportServices.size() * basicNetWork.getFiberLinks().size() * 1.0);
//        double res = new BigDecimal(allRecoveryRate).setScale(5, BigDecimal.ROUND_HALF_UP).doubleValue();
//        List<Double> serviceRecoveryRate = weaver.getServiceRecoveryRate();
//        serviceRecoveryRate.add(res);

        //恢复的业务个数
        int allRecoveryNum = 0;
        for (DemandReportService t : demandReportServices) {
            if (trafficMap.get(t)) {
                allRecoveryNum++;
            }
        }
        //经师姐审阅后，新的业务恢复率算法
        Double sum = 0.0;
        int times = 0;
        if (recoveryRateList == null) {
            throw new BaseException("每一次的业务恢复率计算不出");
        }
        for (Double recoveryRate : recoveryRateList) {
            if (recoveryRate != null && recoveryRate != 0.0) {
                sum = sum + recoveryRate;
                times++;
            }
        }
        Double resNew = new BigDecimal(sum / times * 1.0).setScale(5, BigDecimal.ROUND_HALF_UP).doubleValue();
        Map<String, Double> map = new HashMap<>();
        map.put("业务恢复率", resNew);
        map.put("恢复的业务个数", (double) allRecoveryNum);
        map.put("总fiber链路数", (double) basicNetWork.getFiberLinks().size());
        map.put("总业务数", (double) basicNetWork.getFiberLinks().size());
        return map;
    }
    @Override
    public  Object getBreakPort(@MParam("当前的登陆的用户") LoginUserDto loginUserDto,
                                      @MParam("项目的ID") String pId,
                                      @MParam("节点id") String nodeId,
                                      @MParam("单断的端口id组合") List<Integer> portIds)
                                        throws BaseException{
        Project project = ProjectFactory.getObjectFromFile(pId, ProjectFactory.storePath);
        List<DemandReportService> services=project.getDemandList();
        Map<String,List<IBasicNetWork.PortL>> portMsg=project.getBasicNetWork().getPorts();
        List<IBasicNetWork.PortL> nodePortMsg=project.getBasicNetWork().getPorts().get(nodeId);

        List<TbKangHuiServiceUtil.DanDuanDto> portBreakDtos = new ArrayList<>();

        for(int portId:portIds){//遍历所有的毁坏端口，每次计算对应的毁坏情况并记录
          for(IBasicNetWork.PortL port:nodePortMsg){
              if(port.getId()==portId){
                if(port.getStatus().equals("free")){
                    //空闲端口损坏时候，所有业务不受影响
                    continue;
                }else{
                    IBasicNetWork.BasicLink link = port.getLink(); //损坏端口所在链路

                    //业务端口受到损坏，影响当前业务
                    for(DemandReportService t:services){
                        if(t.getName().equals(port.getStatus())){ //找到了该端口对应的业务
                            port.setStatus("break");
                            //为该业务寻找同链路上的空闲端口
                            for(IBasicNetWork.PortL port2:nodePortMsg){
                                if(port2.getLink()==link&&port2.getStatus().equals("free")){//找到了同链路的替代端口
                                    port2.setStatus(t.getName());
                                    TbKangHuiServiceUtil.RouteType workRouteType= TbKangHuiServiceUtil.routeType(t.getWorkRoute());
                                    TbKangHuiServiceUtil.RouteType protectRouteType= TbKangHuiServiceUtil.routeType(t.getProtectRoute());
                                    TbKangHuiServiceUtil.DanDuanDto danDuanDto= new TbKangHuiServiceUtil.DanDuanDto(t.getId(), t.getName(), t.getNodeHeadName(), t.getNodeTailName(),
                                            t.getYear(), t.getLayer(), t.getProtect(), true, "找到同链路的备用端口"+port.getId()+"->"+port2.getId(),
                                            workRouteType,protectRouteType,workRouteType,protectRouteType);
                                    portBreakDtos.add(danDuanDto);
                                    break;
                                }else{//没有找到同链路的切换端口
                                    List<String> breakLinkIds=new ArrayList<>();
                                    breakLinkIds.add(link.getId());
                                    getBreakOneByOne(loginUserDto,pId,breakLinkIds ,null);  //如果链路端口全部损坏，则相当于链路单断
//                                    Set<String> linkSet=new HashSet<>();
//                                    List<IBasicNetWork.BasicLink> links=project.getBasicNetWork().getBasicLinksByLayer( IBasicNetWork.LayerEnum.getLayerEnum(link.getLayer()) );
//                                    for(Map.Entry<String,List<IBasicNetWork.PortL>> portMsg2:portMsg.entrySet()){
//                                        for(IBasicNetWork.PortL port5: portMsg2.getValue()){
//                                            if(port5.getStatus().equals("free")){
//                                                linkSet.add(port5.getLink().getLinkId());
//                                            }
//                                        }
//                                    }
//                                    Set<IBasicNetWork.BasicLink> oklinks=new HashSet<>();
//                                    for(IBasicNetWork.BasicLink link2:links){
//                                        if (linkSet.contains(link2.getLinkId())){
//                                            oklinks.add(link2);
//                                        }
//                                    }
                                }
                            }
                        break; //因为一个端口只承载一条业务  所以进行完一次上述操作就可以结束对业务的遍历
                        }
                    }
                }
              }
          }


        }

        return portBreakDtos;
    }

}
